package create.singleton;

import java.util.concurrent.*;

/**
 * Created by lie on 2017/10/30.
 * 测试类
 * @see #testHDemo() 饿汉类的测试
 * @see #testLazyDemo()
 * @see #testLazyDemo2() 这2个都是懒汉的非安全的测试，其中一个用了callable来展示了要注意的一个点
 * @see #testLazySyncDemo() 线程安全的懒汉
 */
public class Test {

    public static void main(String[] args){
//        testHDemo();
//        testLazyDemo();
//        testLazyDemo2();
//        testLazySyncDemo();
        testStaticInnerClassDemo();
    }

    private static void testStaticInnerClassDemo() {
        System.out.println(StaticInnerClassDemo.getInstance());
        System.out.println(StaticInnerClassDemo.getInstance());
        System.out.println(StaticInnerClassDemo.getInstance());
        System.out.println(StaticInnerClassDemo.getInstance());
        System.out.println(StaticInnerClassDemo.getInstance());
        System.out.println(StaticInnerClassDemo.getInstance());
    }

    private static void testLazySyncDemo() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(LazySyncDemo.getInstance());
            }
        };
        ExecutorService pool = Executors.newCachedThreadPool();
        pool.execute(runnable);
        pool.execute(runnable);
        pool.execute(runnable);
        pool.execute(runnable);
        pool.execute(runnable);
        pool.shutdown();
//        create.singleton.LazySyncDemo@3a89f671
//        create.singleton.LazySyncDemo@3a89f671
//        create.singleton.LazySyncDemo@3a89f671
//        create.singleton.LazySyncDemo@3a89f671
//        create.singleton.LazySyncDemo@3a89f671
        //这就安全的了
    }

    private static void testLazyDemo2() {
        Callable<LazyDemo> callable = new Callable<LazyDemo>() {
            @Override
            public LazyDemo call() throws Exception {
                return LazyDemo.getInstance();
            }
        };

        ExecutorService pool = Executors.newCachedThreadPool();
        Future<LazyDemo> submit1 = pool.submit(callable);
        Future<LazyDemo> submit2 = pool.submit(callable);
        Future<LazyDemo> submit3 = pool.submit(callable);
        Future<LazyDemo> submit4 = pool.submit(callable);
        Future<LazyDemo> submit5 = pool.submit(callable);
        Future<LazyDemo> submit6 = pool.submit(callable);
        try {
//            System.out.println(pool.submit(callable).get());//直接get因为会产生阻塞行为——所以会影响下面的submit的执行
//            System.out.println(pool.submit(callable).get());
//            System.out.println(pool.submit(callable).get());
//            System.out.println(pool.submit(callable).get());
//            System.out.println(pool.submit(callable).get());
//            System.out.println(pool.submit(callable).get());

            System.out.println(submit1.get());//而像这样，已经都submit过了，再来逐个get，就能看到不安全了
            System.out.println(submit2.get());
            System.out.println(submit3.get());
            System.out.println(submit4.get());
            System.out.println(submit5.get());
            System.out.println(submit6.get());
//            create.singleton.LazyDemo@1bf7d825
//            create.singleton.LazyDemo@1bf7d825
//            create.singleton.LazyDemo@1bf7d825
//            create.singleton.LazyDemo@45a86eeb
//            create.singleton.LazyDemo@2d552459

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }finally {
            pool.shutdown();
        }

    }

    private static void testLazyDemo() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println(LazyDemo.getInstance());
            }
        };
        ExecutorService pool = Executors.newCachedThreadPool();
        pool.execute(runnable);
        pool.execute(runnable);
        pool.execute(runnable);
        pool.execute(runnable);
        pool.execute(runnable);
        pool.shutdown();
        //create.singleton.LazyDemo@40147f91
//        create.singleton.LazyDemo@40147f91
//            create.singleton.LazyDemo@421674f0
//        create.singleton.LazyDemo@40147f91
//        create.singleton.LazyDemo@40147f91
        //如上所示，会存在着线程安全问题

    }

    private static void testHDemo() {
        System.out.println(HDemo.getInstance());
        System.out.println(HDemo.getInstance());
        //结果一致
    }
}
